/**
 * 
 */
package com.gr.staffpm.notes.activity.service;

import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.joda.time.DateTime;
import org.joda.time.Instant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.gr.staffpm.datatypes.Activities;
import com.gr.staffpm.datatypes.Activity;
import com.gr.staffpm.datatypes.Task;
import com.gr.staffpm.datatypes.User;
import com.gr.staffpm.notes.activity.ActivityMessage;
import com.gr.staffpm.notes.activity.dao.ActivityDAO;
import com.gr.staffpm.notes.push.ActivityService;

/**
 * Default implementation of the {@link ActivityService} interface.  This service implements
 * operations related to Activity Notifications data.
 * 
 * @author Graham Rhodes 21 Feb 2011 00:24:31
 */
@Transactional
@Service("activityService")
public class DefaultActivityDaoService implements IActivityDaoService {

    private ActivityDAO activityDao;

    @Autowired
    public void setActivityDAO(ActivityDAO activityDao) {
        this.activityDao = activityDao;
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.notes.activity.service.ActivityService#getRecentActivityForUser(int)
     */
    @Override
    public List<Activity> getRecentActivityForUser(User user) {
        Calendar cal = Calendar.getInstance();
        Date end = cal.getTime();
        cal.add(Calendar.DAY_OF_MONTH, -7);
        Date start = cal.getTime();
        List<Activity> activities = activityDao.getRecentActivityForUser(user, start, end);
        Collections.sort(activities, Collections.reverseOrder());
        if (activities.size() > 5)
            activities = activities.subList(0, 5);
        return activities;
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.notes.activity.service.IActivityDaoService#getNewCommentActivityType()
     */
    @Override
    public Activities getNewCommentActivityType() {
        return activityDao.getActivityType(Activities.NEW_COMMENT);
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.notes.activity.service.IActivityDaoService#addActivity(com.gr.staffpm.datatypes.Activities, com.gr.staffpm.datatypes.User, com.gr.staffpm.notes.activity.ActivityMessage, com.gr.staffpm.datatypes.User)
     */
    @Override
    public void addActivity(Activities activityType, User notified, ActivityMessage msg, User creator) {
        activityDao.addActivity(activityType, notified, msg.getTask(), true, creator, msg.getTimestamp().toDate());
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.notes.activity.service.IActivityDaoService#updateActivity(com.gr.staffpm.datatypes.Activity)
     */
    @Override
    public void updateActivity(Activity activity) {
        activityDao.updateActivity(activity);
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.notes.activity.service.IActivityDaoService#getNewActivityCount(com.gr.staffpm.datatypes.User)
     */
    @Override
    public int getNewActivityCount(User user) {
        return activityDao.getNewActivityCount(user);
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.notes.activity.service.IActivityDaoService#getActivityForUserAndDate(com.gr.staffpm.datatypes.User)
     */
    @Override
    public List<Activity> getActivityForUserAndDate(User user, Date dateOfActivity) {
        DateTime start = new DateTime(dateOfActivity).withTime(0, 0, 0, 0);
        DateTime end = new DateTime(dateOfActivity).withTime(23, 0, 0, 0);
        List<Activity> a = activityDao.getRecentActivityForUser(user, start.toDate(), end.toDate());
        return a;
    }

    /**
     * @return
     */
    private Activities getTaskAcceptedActivityType() {
        return activityDao.getActivityType(Activities.TASK_RESOLUTION_ACCEPTED);
    }

    /**
     * @return
     */
    private Activities getTaskRejectedActivityType() {
        return activityDao.getActivityType(Activities.TASK_RESOLUTION_REJECTED);
    }

    /**
     * @return
     */
    private Activities getTaskSubmittedActivityType() {
        return activityDao.getActivityType(Activities.TASK_SUBMITTED_FOR_APPROVAL);
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.notes.activity.service.IActivityDaoService#notifyAssigneeOfComment(com.gr.staffpm.datatypes.Task, com.gr.staffpm.datatypes.User)
     */
    @Override
    public void notifyAssigneeOfComment(Task task, User currUser) {
        //Create comment activity
        ActivityMessage msg = new ActivityMessage(task, new Instant().toDateTime(), com.gr.staffpm.notes.activity.Activity.newComment(task, currUser));
        addActivity(getNewCommentActivityType(), task.getAssignee(), msg, currUser);
        ActivityService.getInstance().sendAsyncUser(task.getAssignee(), msg);
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.notes.activity.service.IActivityDaoService#notifyAssigneeOfAcceptance(com.gr.staffpm.datatypes.Task, com.gr.staffpm.datatypes.User)
     */
    @Override
    public void notifyAssigneeOfAcceptance(Task task, User currUser) {
        //Create acceptance activity
        ActivityMessage msg = new ActivityMessage(task, new Instant().toDateTime(), com.gr.staffpm.notes.activity.Activity.taskResolved(task, currUser));
        addActivity(getTaskAcceptedActivityType(), task.getAssignee(), msg, currUser);
        ActivityService.getInstance().sendAsyncUser(task.getAssignee(), msg);
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.notes.activity.service.IActivityDaoService#notifyAssigneeOfRejection(com.gr.staffpm.datatypes.Task, com.gr.staffpm.datatypes.User)
     */
    @Override
    public void notifyAssigneeOfRejection(Task task, User currUser) {
        //Create rejection activity
        ActivityMessage msg = new ActivityMessage(task, new Instant().toDateTime(), com.gr.staffpm.notes.activity.Activity.taskResolutionRejected(task, currUser));
        addActivity(getTaskRejectedActivityType(), task.getAssignee(), msg, currUser);
        ActivityService.getInstance().sendAsyncUser(task.getAssignee(), msg);
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.notes.activity.service.IActivityDaoService#notifyAssigneeOfSubmission(com.gr.staffpm.datatypes.Task, com.gr.staffpm.datatypes.User)
     */
    @Override
    public void notifyAssigneeOfSubmission(Task task, User currUser) {
        //Create submission activity
        ActivityMessage msg = new ActivityMessage(task, new Instant().toDateTime(), com.gr.staffpm.notes.activity.Activity.taskSubmittedForApproval(task, currUser));
        addActivity(getTaskSubmittedActivityType(), task.getAssignee(), msg, currUser);
        ActivityService.getInstance().sendAsyncUser(task.getAssignee(), msg);
    }

}
